<template>
  <div class="table-sql-preview-v2">
    <div class="preview-container">
      <!-- SQL类型选择 -->
      <div class="preview-header mb-4">
        <el-radio-group v-model="previewType" size="large">
          <el-radio-button label="create">
            <el-icon class="mr-1"><Plus /></el-icon>
            创建表 SQL
          </el-radio-button>
          <el-radio-button label="alter" v-if="!isNewTable">
            <el-icon class="mr-1"><Edit /></el-icon>
            修改表 SQL
          </el-radio-button>
          <el-radio-button label="drop">
            <el-icon class="mr-1"><Delete /></el-icon>
            删除表 SQL
          </el-radio-button>
        </el-radio-group>
      </div>

      <!-- SQL内容 -->
      <div class="sql-content bg-gray-900 rounded-lg p-4 relative">
        <div class="absolute top-4 right-4 flex items-center space-x-2">
          <el-button
            v-if="showCopyButton"
            size="small"
            type="primary"
            plain
            @click="copySQL"
          >
            <el-icon><CopyDocument /></el-icon>
            复制
          </el-button>
          <el-tag type="info" size="small">{{ databaseTypeLabel }}</el-tag>
        </div>
        
        <pre class="sql-code text-sm text-gray-100 font-mono overflow-x-auto"><code v-html="highlightedSQL"></code></pre>
      </div>
      
      <!-- SQL风险提示 -->
      <div v-if="sqlRisks.length > 0" class="sql-risks mt-4 p-4 bg-yellow-50 rounded-lg border border-yellow-200">
        <div class="flex items-center mb-2">
          <el-icon class="text-yellow-600 mr-2"><Warning /></el-icon>
          <h4 class="text-sm font-medium text-yellow-800">潜在风险警告</h4>
        </div>
        <ul class="list-disc pl-5 mt-1 space-y-2">
          <li v-for="(risk, index) in sqlRisks" :key="index" class="text-sm text-yellow-700">
            {{ risk.message }}
            <div v-if="risk.type === 'NOT_NULL_WITHOUT_DEFAULT'" class="mt-1 ml-2 text-xs text-yellow-600">
              解决方案: 为列添加默认值，或先更新现有NULL值
            </div>
            <div v-if="risk.type === 'TYPE_CONVERSION'" class="mt-1 ml-2 text-xs text-yellow-600">
              解决方案: 确保数据兼容新类型，可能需要先执行UPDATE语句进行转换
            </div>
            <div v-if="risk.type === 'LENGTH_REDUCTION'" class="mt-1 ml-2 text-xs text-yellow-600">
              解决方案: 检查现有数据长度，确保不会导致截断，或增加字段长度
            </div>
          </li>
        </ul>
      </div>

      <!-- 说明信息 -->
      <div class="preview-info mt-4 p-4 bg-blue-50 rounded-lg border border-blue-200">
        <p class="text-sm text-blue-800">
          <el-icon class="mr-1 align-middle"><InfoFilled /></el-icon>
          <span v-if="previewType === 'create'">
            这是根据当前表结构生成的创建表SQL语句。
          </span>
          <span v-else-if="previewType === 'alter'">
            这是根据表结构变更生成的修改表SQL语句。
          </span>
          <span v-else>
            这是删除表的SQL语句，执行后将永久删除表及其所有数据。
          </span>
        </p>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import { Plus, Edit, Delete, CopyDocument, InfoFilled, Warning } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { useTableStructureStore } from '@/stores/tableStructureStore'

const props = defineProps({
  tableData: {
    type: Object,
    required: true
  },
  databaseType: {
    type: String,
    default: 'mysql'
  },
  isNewTable: {
    type: Boolean,
    default: false
  },
  showCopyButton: {
    type: Boolean,
    default: false
  },
  originalStructure: {
    type: Object,
    default: null
  }
})

const tableStructureStore = useTableStructureStore()

// 响应式数据
const previewType = ref('create')

// 数据库类型标签
const databaseTypeLabel = computed(() => {
  const labels = {
    mysql: 'MySQL',
    postgresql: 'PostgreSQL',
    sqlite: 'SQLite',
    sqlserver: 'SQL Server',
    dameng: '达梦数据库'
  }
  return labels[props.databaseType] || props.databaseType.toUpperCase()
})

// 生成SQL
const generatedSQL = computed(() => {
  const structure = {
    ...props.tableData,
    databaseType: props.databaseType,
    database: props.tableData.database || ''
  }

  switch (previewType.value) {
    case 'create':
      return tableStructureStore.generateCreateSQL(structure)
    
    case 'alter':
      return tableStructureStore.generateAlterSQL(structure)
    
    case 'drop':
      return generateDropSQL()
    
    default:
      return ''
  }
})

// SQL语法高亮
const highlightedSQL = computed(() => {
  let sql = generatedSQL.value
  
  // 关键字高亮
  const keywords = [
    'CREATE', 'TABLE', 'ALTER', 'DROP', 'ADD', 'MODIFY', 'COLUMN',
    'PRIMARY', 'KEY', 'FOREIGN', 'REFERENCES', 'ON', 'DELETE', 'UPDATE',
    'CASCADE', 'RESTRICT', 'NOT', 'NULL', 'AUTO_INCREMENT', 'DEFAULT',
    'COMMENT', 'ENGINE', 'CHARSET', 'COLLATE', 'INDEX', 'UNIQUE',
    'IF', 'EXISTS', 'INT', 'VARCHAR', 'TEXT', 'DATETIME', 'TIMESTAMP',
    'DECIMAL', 'FLOAT', 'DOUBLE', 'BOOLEAN', 'JSON', 'BLOB'
  ]
  
  // 替换关键字
  keywords.forEach(keyword => {
    const regex = new RegExp(`\\b${keyword}\\b`, 'gi')
    sql = sql.replace(regex, `<span class="sql-keyword">${keyword}</span>`)
  })
  
  // 字符串高亮
  sql = sql.replace(/'([^']*)'/g, `<span class="sql-string">'$1'</span>`)
  
  // 注释高亮
  sql = sql.replace(/(--.*$)/gm, `<span class="sql-comment">$1</span>`)
  
  // 反引号标识符高亮
  sql = sql.replace(/`([^`]+)`/g, `<span class="sql-identifier">\`$1\`</span>`)
  
  return sql
})

// 生成删除表SQL
const generateDropSQL = () => {
  const tableName = props.tableData.name
  const database = props.tableData.database
  
  switch (props.databaseType) {
    case 'mysql':
      return database 
        ? `DROP TABLE IF EXISTS \`${database}\`.\`${tableName}\`;`
        : `DROP TABLE IF EXISTS \`${tableName}\`;`
    
    case 'postgresql':
      return `DROP TABLE IF EXISTS "${tableName}" CASCADE;`
    
    case 'sqlite':
      return `DROP TABLE IF EXISTS "${tableName}";`
    
    case 'sqlserver':
      const schema = props.tableData.schema || 'dbo'
      return `IF OBJECT_ID('[${schema}].[${tableName}]', 'U') IS NOT NULL\n  DROP TABLE [${schema}].[${tableName}];`
    
    case 'dameng':
      return `DROP TABLE IF EXISTS "${tableName}" CASCADE;`
    
    default:
      return `DROP TABLE ${tableName};`
  }
}

// 复制SQL
const copySQL = async () => {
  try {
    await navigator.clipboard.writeText(generatedSQL.value)
    ElMessage.success('SQL已复制到剪贴板')
  } catch (err) {
    ElMessage.error('复制失败，请手动选择复制')
  }
}

// 监听是否为新表
watch(() => props.isNewTable, (newVal) => {
  if (newVal) {
    previewType.value = 'create'
  }
}, { immediate: true })

// SQL潜在风险检测
const sqlRisks = computed(() => {
  const risks = [];
  
  // 仅对修改模式的SQL进行风险检测
  if (previewType.value === 'alter' && !props.isNewTable) {
    // 检测未指定默认值的非空列
    const notNullColumnsWithoutDefault = props.tableData.columns.filter(
      col => col.notNull && !col.defaultValue
    );
    
    if (notNullColumnsWithoutDefault.length > 0) {
      risks.push({
        type: 'NOT_NULL_WITHOUT_DEFAULT',
        message: `以下列设置了非空约束但没有默认值，可能导致修改失败: ${
          notNullColumnsWithoutDefault.map(col => col.name).join(', ')
        }`,
        columns: notNullColumnsWithoutDefault.map(col => col.name)
      });
    }
    
    // 检测列类型变更的风险
    if (props.originalStructure) {
      const typeChanges = props.tableData.columns.filter(newCol => {
        const oldCol = props.originalStructure.columns.find(c => c.name === newCol.name);
        return oldCol && oldCol.type !== newCol.type;
      });
      
      if (typeChanges.length > 0) {
        risks.push({
          type: 'TYPE_CONVERSION',
          message: `以下列改变了数据类型，可能导致数据转换问题: ${
            typeChanges.map(col => `${col.name} (${col.type})`).join(', ')
          }`,
          columns: typeChanges.map(col => col.name)
        });
      }
    }
    
    // 检测长度减小的情况
    if (props.originalStructure) {
      const lengthReductions = props.tableData.columns.filter(newCol => {
        const oldCol = props.originalStructure.columns.find(c => c.name === newCol.name);
        return oldCol && 
               oldCol.length && newCol.length && 
               parseInt(newCol.length) < parseInt(oldCol.length);
      });
      
      if (lengthReductions.length > 0) {
        risks.push({
          type: 'LENGTH_REDUCTION',
          message: `以下列减小了长度，可能导致数据截断: ${
            lengthReductions.map(col => col.name).join(', ')
          }`,
          columns: lengthReductions.map(col => col.name)
        });
      }
    }
  }
  
  return risks;
});
</script>

<style lang="scss" scoped>
.table-sql-preview-v2 {
  .sql-content {
    min-height: 300px;
    max-height: 600px;
    overflow-y: auto;
    
    pre {
      margin: 0;
      white-space: pre-wrap;
      word-wrap: break-word;
    }
  }
  
  // SQL语法高亮样式
  :deep(.sql-keyword) {
    color: #f92672;
    font-weight: bold;
  }
  
  :deep(.sql-string) {
    color: #a6e22e;
  }
  
  :deep(.sql-comment) {
    color: #75715e;
    font-style: italic;
  }
  
  :deep(.sql-identifier) {
    color: #66d9ef;
  }
  
  // 自定义滚动条
  .sql-content::-webkit-scrollbar {
    width: 8px;
    height: 8px;
  }
  
  .sql-content::-webkit-scrollbar-track {
    background: rgba(255, 255, 255, 0.1);
    border-radius: 4px;
  }
  
  .sql-content::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.3);
    border-radius: 4px;
    
    &:hover {
      background: rgba(255, 255, 255, 0.5);
    }
  }
}

// 暗色模式
@media (prefers-color-scheme: dark) {
  .table-sql-preview-v2 {
    .preview-info {
      background-color: rgba(59, 130, 246, 0.1);
      border-color: rgba(59, 130, 246, 0.3);
      
      p {
        color: #93bbfc;
      }
    }
  }
}
</style> 